#ifndef _SHD_POSITION_HLSL_
#define _SHD_POSITION_HLSL_

#include "./shd_texture_reader.hlsl"

float3 Position( int cur_index, int qtt_index, int cur_time, int qtt_time ) {
	// position
//	float3 position = tex_position_read( cur_index, qtt_index, 0, 1 );

	// offset
	return tex_offset_read( cur_index, qtt_index, cur_time, qtt_time );

//	position += offset;
//	return position;
};

float3 Position_Linear( int cur_index, int qtt_index, int cur_time, int qtt_time, float interpol_coef ) {
	if( cur_time + 1 < qtt_time ) {
		return lerp(
			Position( cur_index, qtt_index, cur_time, qtt_time ),
			Position( cur_index, qtt_index, cur_time + 1, qtt_time ),
			interpol_coef
		);
	}
	// else
	return Position( cur_index, qtt_index, cur_time, qtt_time );
};

float3 Position_Quadratic( int cur_index, int qtt_index, int cur_time, int qtt_time, float interpol_coef ) {
	int time_mod = cur_time % 2;
	int time = cur_time - time_mod;
	if( time + 2 < qtt_time ) {
		float coef2 = ( interpol_coef + time_mod ) / 2.0;
		float coef1 = 1.0 - coef2;
		return	Position( cur_index, qtt_index, time, qtt_time ) * coef1 * coef1 +
				Position( cur_index, qtt_index, time + 1, qtt_time ) * 2.0 * coef1 * coef2 +
				Position( cur_index, qtt_index, time + 2, qtt_time ) * coef2 * coef2;
	}
	// else
	return Position_Linear( cur_index, qtt_index, cur_time, qtt_time, interpol_coef );
			
/*
	return lerp(
		lerp(
			Position( cur_index, qtt_index, time, qtt_time ),
			Position( cur_index, qtt_index, time + 1, qtt_time ),
			coef
		),
		lerp(
			Position( cur_index, qtt_index, time + 1, qtt_time ),
			Position( cur_index, qtt_index, time + 2, qtt_time ),
			coef
		),
		coef
	);
*/
};

float3 Position_Cubic( int cur_index, int qtt_index, int cur_time, int qtt_time, float interpol_coef ) {
	int time_mod = cur_time % 3;
	int time = cur_time - time_mod;
	if( time + 3 < qtt_time ) {
		float coef2 = ( interpol_coef + time_mod ) / 3.0;
		float coef1 = 1.0 - coef2;
		return	Position( cur_index, qtt_index, time, qtt_time ) * coef1 * coef1 * coef1 +
				Position( cur_index, qtt_index, time + 1, qtt_time ) * 3.0 * coef1 * coef1 * coef2 +
				Position( cur_index, qtt_index, time + 2, qtt_time ) * 3.0 * coef1 * coef2 * coef2 +
				Position( cur_index, qtt_index, time + 3, qtt_time ) * coef2 * coef2 * coef2;
	}
	// else
	return Position_Linear( cur_index, qtt_index, cur_time, qtt_time, interpol_coef );

};

float3 Position_Hermite( int cur_index, int qtt_index, int cur_time, int qtt_time, float interpol_coef ) {

	if( cur_time >= qtt_time - 1 )
		return Position( cur_index, qtt_index, qtt_time - 1, qtt_time );

	// TODO - Only one init plz
	matrix coeficients;
	coeficients[0][0] = 2;	coeficients[0][1] = -2;	coeficients[0][2] = 1;	coeficients[0][3] = 1;
	coeficients[1][0] = -3;	coeficients[1][1] = 3;	coeficients[1][2] = -2;	coeficients[1][3] = -1;
	coeficients[2][0] = 0;	coeficients[2][1] = 0;	coeficients[2][2] = 1;	coeficients[2][3] = 0;
	coeficients[3][0] = 1;	coeficients[3][1] = 0;	coeficients[3][2] = 0;	coeficients[3][3] = 0;

	float3 pos1 = Position( cur_index, qtt_index, cur_time, qtt_time );
	float3 pos2 = Position( cur_index, qtt_index, cur_time + 1, qtt_time );
	float3 der1 = ( cur_time == 0 ? // if it's the 1st
		pos2 - pos1 :
		pos2 - Position( cur_index, qtt_index, cur_time - 1, qtt_time )
	);
	float3 der2 = ( cur_time == qtt_time - 1 ? // if it's the last
		pos2 - pos1 :
		Position( cur_index, qtt_index, cur_time + 1, qtt_time ) - pos1
	);

	float4 time_interpol = float4(
		interpol_coef*interpol_coef*interpol_coef,
		interpol_coef*interpol_coef,
		interpol_coef,
		1
	);

	return float3(
		mul( mul( time_interpol, coeficients ), float4( pos1[0], pos2[0], der1[0], der2[0] ) ),
		mul( mul( time_interpol, coeficients ), float4( pos1[1], pos2[1], der1[1], der2[1] ) ),
		mul( mul( time_interpol, coeficients ), float4( pos1[2], pos2[2], der1[2], der2[2] ) )
	);

};

float3 Position_Interpol( int cur_index, int qtt_index, int cur_time, int qtt_time, float interpol_coef ) {

	if( g_iInterpolationType == 0 ) // None
		return Position( cur_index, qtt_index, cur_time, qtt_time );
	else if( g_iInterpolationType == 1 ) // Linear
		return Position_Linear( cur_index, qtt_index, cur_time, qtt_time, interpol_coef );
	else if( g_iInterpolationType == 2 ) // Quadratic
		return Position_Quadratic( cur_index, qtt_index, cur_time, qtt_time, interpol_coef );
	else if( g_iInterpolationType == 3 ) // Cubic
		return Position_Cubic( cur_index, qtt_index, cur_time, qtt_time, interpol_coef );
	else if( g_iInterpolationType == 4 ) // Hermite
		return Position_Hermite( cur_index, qtt_index, cur_time, qtt_time, interpol_coef );

	return float3( 0.0, 0.0, 0.0 );
};

#endif // _SHD_POSITION_HLSL_
